package tp.igl;


    /**
     *<b> Adresse est la classe representant un Masque d'un réseau</b>
     * <p>
     *  Le masque prend que quelque valeurs définie ,celles qui ne contient pas des
     * facteur "01" dans l'écriture binaire de ce masque.
     * </p>
     * @author Redouane
     * @author PNR KACIMI HACINI
     * @see Segement
     * @see Adresse
     * @author Redouane
     */


    public class Masque extends Adresse {
        
    /**
    *Constructeur AdresseIP
    * <p>
    *A la construction du Masque prend les valeurs fournie en parametre.
    * </p>
    * @param seg1  le segement a affecté dans la position 1
    * @param seg2  le segement a affecté dans la position 2
    * @param seg3  le segement a affecté dans la position 3
    * @param seg4  le segement a affecté dans la position 4
    *
   */
        
        public Masque(Segment seg1,Segment seg2,Segment seg3,Segment seg4) {
            super(seg1,seg2,seg3,seg4);
            if (this.toString().contains("01"));

    }
    
    /**
     * Modifie le Masque pour lui donner la prochaine valeur (plus grande)
     * Les masque sont une suite binaire de 1 suivie d'un 0
     * Pour trouver le prochain masque on cherche le premier segment dont la valeur est différente de 255 en partant de la gauche
     * puis on y  remplace le premier 1, rencontré en partant de la gauche, par 0
     * 
     */
    public void toNextMasque(){
    int i=0;
    while ((this.adresse[i].valeur==255)&&(i<3)) i++;
    if(i==3 && this.adresse[i].valeur==252 )
           return ;
    Integer val=new Integer(this.adresse[i].valeur);
    this.adresse[i].valeur=Integer.parseInt(this.adresse[i].toString(true).replaceFirst("0", "1"),2);
    }
        
    /**
     * Modifie le Masque pour lui donner la précedente valeur (plus petite)
     * Les masque sont une suite binaire de 1 suivie d'un 0
     * Pour trouver le precedent masque on cherche le premier segment dont la valeur est différente de 255 en partant de la gauche
     * puis on y  remplace le dernier 1, rencontré en partant de la gauche, par 0
     * 
     */
    public void toPreviousMasque(){
    int i=0;
    while ((this.adresse[i].valeur==255)&&(i<3)) i++;
    if(i!=0 && this.adresse[i].valeur==0) i--;
    else if(i==0 && this.adresse[i].valeur==0) return;

    Integer val=new Integer(this.adresse[i].valeur);
    String str=this.adresse[i].toString(true);
    String str2;
    int j=str.lastIndexOf("1");
    str2=str.substring(0, j)+"0"+str.substring(j+1);
    this.adresse[i].valeur=Integer.parseInt(str2,2);
    }     
        
    /**
     * Le nombre magique est un nombre qui facilite les calculs des adresses des sous réseaux
     * il est généré en fonction du nombre de réseaux à créer et de l'adresse du réseau
     * @param nbrReseaux le nombre de sous-réseaux à créer 
     * @return un objet de type NbrMagic
     */
    public NbrMagic getNbMagic(int nbrReseaux){
        nbrReseaux=Reseau.arronderNombre(nbrReseaux);
        int i=0;
        Float nbMagic;
        while(this.getAdresse()[i].getValeur()==255){
            i++;
        }
        nbMagic=new Float(256-this.getAdresse()[i].getValeur())/nbrReseaux;
        if(nbMagic<1){
            nbMagic=nbMagic*256;
            i++;
        }
        return new NbrMagic(nbMagic.intValue(), i);
    }
    
    /**
     * Calcule le masque de sous-réseaux à partir des informations du réseau et du nombre de sous-réseaux à créer
     * Pour ce faire, on doit utiliser le nombre magique
     * @param nbrReseaux
     * @return le masque de sous-réseaux
     */
    public Masque getSubnetMasque(int nbrReseaux){
        nbrReseaux=Reseau.arronderNombre(nbrReseaux);
        int i=0;
        NbrMagic nb=getNbMagic(nbrReseaux);
        Masque masque=new Masque(new Segment(0),new Segment(0),new Segment(0),new Segment(0));
        masque.setAdresse(this);
        masque.getAdresse()[nb.getOc()].setValeur(256-nb.getVal());
        i=nb.getOc()-1;
        while(i>=0 && masque.getAdresse()[i].getValeur()!=255){
            masque.getAdresse()[i].setValeur(255);
            i--;
        }
        return masque;
    }
    
  /**
    * Retourne le nombres maximal de sous-reseaux qu'on puisse le  crée à partir de masque
    * @return le nombres maximal de sous-reseaux
    */
    public int getNbrMaxSubNets(){
        Double nb = Math.pow(2,this.getNbrDeZero()-2);
        return nb.intValue();
    }
    
    @Override
    public boolean equals(Object obj) {
        return super.equals(obj); //la méthode la classe mère (Adresse)
    }
    
}
